package com.suarte.core.hibernate;

import com.suarte.core.Currency;
import com.suarte.core.ExchangeRate;
import com.suarte.core.ExchangeRateType;
import com.suarte.core.dao.ExchangeRateDao;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.appfuse.dao.hibernate.GenericDaoHibernate;

import org.springframework.stereotype.Repository;

/**
 * @date Dec 20, 2010
 * @author Ggutierrez
 */
@Repository("exchangeRateDao")
public class ExchangeRateDaoHibernate extends GenericDaoHibernate<ExchangeRate, Long> implements ExchangeRateDao {

    public ExchangeRateDaoHibernate() {
        super(ExchangeRate.class);
    }

    public ExchangeRate findByDate(Date date, Currency fromCurrency, Currency toCurrency, ExchangeRateType type) {
        String hql = "from ExchangeRate this join fetch this.fromCurrency fromCurrency "
                + "  join fetch this.toCurrency toCurrency "
                + " where 1 = 1 ";
        List args = new ArrayList();

        if (date != null) {
            if (type.equals(ExchangeRateType.DIARIA)) {
                args.add(date);
                hql += " and this.date = ?";
            } else if (type.equals(ExchangeRateType.MENSUAL)) {
                args.add(date);
                hql += " and extract(MONTH from this.date) = extract(MONTH from ?)";
            } else if (type.equals(ExchangeRateType.ANUAL)) {
                args.add(date);
                hql += " and extract(YEAR from this.date) = extract(YEAR from ?)";
            }
        }

        if (fromCurrency != null) {
            args.add(fromCurrency);
            args.add(fromCurrency);
            hql += " and (fromCurrency = ? or toCurrency = ?)";
        }

        if (toCurrency != null) {
            args.add(toCurrency);
            args.add(toCurrency);
            hql += " and (fromCurrency = ? or toCurrency = ?)";
        }

        if (type != null) {
            args.add(type);
            hql += " and this.type = ?";
        }

        hql += " order by this.id desc ";

        List results = getHibernateTemplate().find(hql, args.toArray());
        return results != null && !results.isEmpty() ? (ExchangeRate) results.get(0) : null;
    }

    public List<ExchangeRate> findRates(Date date, Currency fromCurrency, Currency toCurrency, ExchangeRateType type) {
        String hql = "from ExchangeRate this join fetch this.fromCurrency fromCurrency "
                + "  join fetch this.toCurrency toCurrency "
                + " where 1 = 1 ";
        List args = new ArrayList();

        if (date != null) {
            if (type != null) {
                if (type.equals(ExchangeRateType.DIARIA)) {
                    args.add(date);
                    hql += " and this.date = ?";
                } else if (type.equals(ExchangeRateType.MENSUAL)) {
                    args.add(date);
                    hql += " and extract (MONTH from this.date) = extract(MONTH from ?)";
                } else if (type.equals(ExchangeRateType.ANUAL)) {
                    args.add(date);
                    hql += " and extract (YEAR from this.date) = extract(MONTH from ?)";
                }
            } else {
                args.add(date);
                hql += " and this.date = ?";
            }
        }

        if (fromCurrency != null) {
            args.add(fromCurrency);
            args.add(fromCurrency);
            hql += " and (fromCurrency = ? or toCurrency = ?)";
        }

        if (toCurrency != null) {
            args.add(toCurrency);
            args.add(toCurrency);
            hql += " and (fromCurrency = ? or toCurrency = ?)";
        }

        if (type != null) {
            args.add(type);
            hql += " and this.type = ?";
        }

        hql += " order by this.id desc ";

        List results = getHibernateTemplate().find(hql, args.toArray());
        return results;
    }
}
